﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


public static class IEnumerableExtensions
{
    public static T SimpleSum<T>(T d1, T d2) where T: class
    {
        return Convert.ToDecimal(d1) + Convert.ToDecimal(d2) as T;
    }

    public static T SimpleProduct<T>(T d1, T d2) where T: class
    {
        return Convert.ToDecimal(d1) * Convert.ToDecimal(d2) as T;
    }

    static T Map<T>(Func<T, T, T> f, IEnumerable<T> enumerable) 
    {
        IEnumerator<T> enumerator = enumerable.GetEnumerator();
        enumerator.MoveNext();
        T res = enumerator.Current;
        while (enumerator.MoveNext())
        {
            res = f(res, enumerator.Current);
        }
        return res;
    }

    public static T Sum<T>(this IEnumerable<T> enumerable) where T:class
    {
        return Map<T>(SimpleSum, enumerable);
    }

    public static T Product<T>(this IEnumerable<T> enumerable) where T : class
    {
        return Map<T>(SimpleProduct, enumerable);
    }

    public static T SimpleMin<T>(T t1, T t2) where T: IComparable<T>
    {
        if (t1.CompareTo(t2) <= 0)
        {
            return t1;
        }
        return t2;
    }

    public static T SimpleMax<T>(T t1, T t2) where T : IComparable<T>
    {
        if (t1.CompareTo(t2) >= 0)
        {
            return t1;
        }
        return t2;
    }
    public static T Min<T>(this IEnumerable<T> enumerable) where T : IComparable<T>
    {
        return Map<T>(SimpleMin, enumerable);
    }

    public static T Max<T>(this IEnumerable<T> enumerable) where T : IComparable<T>
    {
        return Map<T>(SimpleMax, enumerable);
    }

    //public static T Average<T>(this IEnumerable<T> enumerable) where T : class
    //{
    //    return Convert.ToDecimal(enumerable.Sum<T>()) / enumerable.Count();
    //}

    public static void Main()
    {
        List<int> list = new List<int>();
        list.Add(3);
        list.Add(4);
        Console.WriteLine(list.Sum());
    }
}

